package com.siyoumi.app.modules.mall2.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.siyoumi.app.entity.*;
import com.siyoumi.app.modules.mall2.service.SvcM2Sku;
import com.siyoumi.app.modules.mall2.service.SvcM2Spu;
import com.siyoumi.app.modules.mall2.vo.*;
import com.siyoumi.app.service.*;
import com.siyoumi.component.XApp;
import com.siyoumi.component.XBean;
import com.siyoumi.component.http.InputData;
import com.siyoumi.component.http.XHttpContext;
import com.siyoumi.exception.EnumSys;
import com.siyoumi.exception.XException;
import com.siyoumi.mybatispuls.JoinWrapperPlus;
import com.siyoumi.util.XDate;
import com.siyoumi.util.XLog;
import com.siyoumi.util.XReturn;
import com.siyoumi.util.XStr;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class SvcM2SpuImpl
        implements SvcM2Spu {
    @Override
    public JoinWrapperPlus<M2Spu> listQuery(InputData inputData) {
        String spuName = inputData.input("spu_name");
        String groupId = inputData.input("group_id");
        String hot = inputData.input("hot", "");

        JoinWrapperPlus<M2Spu> query = SvcM2Spu.getApp().join();
        query.eq("mspu_x_id", XHttpContext.getX())
                .eq("mspu_del", 0);
        if (XStr.hasAnyText(spuName)) //名称
        {
            query.like("mspu_name", spuName);
        }
        if (XStr.hasAnyText(groupId)) //分组
        {
            query.eq("mspu_group_id", groupId);
        }
        if (XStr.hasAnyText(hot)) {
            String sqlExists = "SELECT 1 FROM zzz_wx_app_main.t_m2_spu_hot WHERE spuh_spu_id = mspu_id";
            switch (hot) {
                case "1": //只显示设置热销的商品
                    query.exists(sqlExists);
                    break;
                case "2": //过滤已设置热销的商品
                    query.notExists(sqlExists);
                    break;
            }
        }

        return query;
    }

    @Override
    public XReturn list(InputData inputData, Boolean searchCount) {
        M2SpuService appSpu = SvcM2Spu.getApp();
        //query
        JoinWrapperPlus<M2Spu> query = listQuery(inputData);
        //join
        query.join(M2Group.table(), "mspu_group_id", "mgroup_id");
        //
        query.select("t_m2_spu.*", "mgroup_name");
        query.orderByAsc("mspu_order")
                .orderByDesc("mspu_create_date");

        IPage<M2Spu> page = new Page<>(inputData.getPageIndex(), inputData.getPageSize(), searchCount);
        //list
        IPage<Map<String, Object>> pageData = appSpu.mapper().getMaps(page, query);
        List<Map<String, Object>> list = pageData.getRecords();
        long count = pageData.getTotal();

        List<Map<String, Object>> listData = list.stream().map(item ->
        {
            M2Spu entitySpu = appSpu.loadEntity(item);
            item.put("id", entitySpu.getKey());

            return item;
        }).collect(Collectors.toList());

        XReturn r = XReturn.getR(0);
        r.setData("list", listData);
        r.setData("count", count);

        return r;
    }

    @Override
    public XReturn info(String spuId) {
        M2Spu entitySpu = SvcM2Spu.getApp().getEntity(spuId, XHttpContext.getX());
        if (entitySpu == null) {
            return EnumSys.ERR_VAL.getR("商品ID异常");
        }

        //规格
        List<SpuAttrVo> listAttrSku = getListAttrSku(entitySpu);
        //规格sku
        List<SpuAttrData> listAttrData = getListAttrData(listAttrSku, true);

        XReturn r = XReturn.getR(0);
        r.setData("entity_spu", entitySpu);
        r.setData("attr", listAttrSku);
        r.setData("attr_sku", listAttrData);

        return r;
    }

    @Override
    public Long getCount(String groupId) {
        InputData inputData = InputData.getIns();
        if (XStr.hasAnyText(groupId)) {
            inputData.put("group_id", groupId);
        }

        JoinWrapperPlus<M2Spu> query = listQuery(inputData);
        return SvcM2Spu.getApp().count(query);
    }

    @Override
    public XReturn delete(List<String> ids) {
        InputData inputData = InputData.fromRequest();
        //商家ID
        JoinWrapperPlus<M2Spu> query = listQuery(inputData);
        query.in("mspu_id", ids);
        List<M2Spu> list = SvcM2Spu.getApp().list(query);
        if (list.size() <= 0) {
            return EnumSys.ERR_VAL.getR("ids异常");
        }

        return XApp.getTransaction().execute(status -> {
            for (M2Spu entitySpu : list) {
                SvcM2Spu.getApp().delete(entitySpu);
            }

            return XReturn.getR(0);
        });
    }

    @Override
    public XReturn edit(InputData inputData, VaM2Spu vo) {


        return null;
    }

    @Override
    public XReturn setAuditStatus(M2Spu entitySpu, Long status, String wxFrom, String desc) {
        return null;
    }

    /**
     * 获取商品规格属性列表
     *
     * @param entitySpu
     */
    @Override
    public List<SpuAttrVo> getListAttrSku(M2Spu entitySpu) {
        String key = SvcM2Spu.getApp().getEntityCacheKey("getListAttrSku|" + entitySpu.getMspu_id());
        List<SpuAttrVo> listVo = XHttpContext.get(key);
        if (listVo != null) {
            return listVo;
        }

        List<M2Attr> listAttr = M2AttrService.getBean().getList(entitySpu.getKey());
        List<M2AttrSku> listAttrSku = M2AttrSkuService.getBean().getList(entitySpu.getKey(), null);
        listVo = listAttr.stream().map(entityAttr ->
        {
            SpuAttrVo vo = new SpuAttrVo(); //属性
            vo.setMattr_id(entityAttr.getKey());
            vo.setMattr_name(entityAttr.getMattr_name());
            vo.setMattr_spu_id(entityAttr.getMattr_spu_id());
            //属性规格
            List<SpuAttrSkuVo> attrSku = listAttrSku.stream()
                    .filter(entityArrSku -> entityArrSku.getMasku_attr_id().equals(entityAttr.getKey()))
                    .map(entityArrSku ->
                    {
                        SpuAttrSkuVo entityAttrVo = new SpuAttrSkuVo();
                        entityAttrVo.setMasku_id(entityArrSku.getKey());
                        entityAttrVo.setMasku_name(entityArrSku.getMasku_name());
                        entityAttrVo.setDoSync(entityArrSku.getMasku_sync() == 1);
                        return entityAttrVo;
                    }).collect(Collectors.toList());
            vo.setAttr_skus(attrSku);

            return vo;
        }).collect(Collectors.toList());
        //
        XHttpContext.set(key, listVo);

        return listVo;
    }

    @Override
    public XReturn saveAttrSku(M2Spu entitySpu, List<SpuAttrVo> listAttr) {
        M2AttrService appAttr = M2AttrService.getBean();
        M2AttrSkuService appAttrSku = M2AttrSkuService.getBean();

        Long attrCountDb = appAttr.getCount(entitySpu.getKey());
        long newAttrCount = listAttr.stream().filter(item -> XStr.isNullOrEmpty(item.getMattr_id())).count();
        if ((newAttrCount + attrCountDb) > SvcM2Spu.getAttrCountMax()) {
            return XReturn.getR(20177, "商品属性最多添加" + SvcM2Spu.getAttrCountMax() + "个");
        }

        List<String> spuAttrIdsDel = new ArrayList<>();
        for (SpuAttrVo spuAttr : listAttr) {
            if (spuAttr.isDelete()) {
                //删除操作
                spuAttrIdsDel.add(spuAttr.getMattr_id());
                continue;
            }

            //属性保存
            M2Attr entityAttr = new M2Attr();
            if (XStr.hasAnyText(spuAttr.getMattr_id())) {
                //编辑名称
                entityAttr = appAttr.getEntity(spuAttr.getMattr_id());
                appAttr.update()
                        .set("mattr_name", spuAttr.getMattr_name())
                        .eq("mattr_id", spuAttr.getMattr_id())
                        .update();
            } else {
                //添加
                entityAttr.setMattr_x_id(entitySpu.getX());
                entityAttr.setMattr_spu_id(entitySpu.getMspu_id());
                entityAttr.setMattr_name(spuAttr.getMattr_name());
                entityAttr.setMattr_order(XDate.toS().intValue()); //排序要系统设置
                entityAttr.setAutoID();
                appAttr.save(entityAttr);
                //添加规格，删除所有sku
                M2SkuService.getBean().deleteBySpuId(entitySpu.getMspu_id());
            }

            //属性规格保存
            Integer order = 0; //自动设置排序
            for (SpuAttrSkuVo attrSku : spuAttr.getAttr_skus()) {
                M2AttrSku entityAttrSku = new M2AttrSku();
                XBean.copyProperties(attrSku, entityAttrSku);
                if (XStr.hasAnyText(attrSku.getMasku_id())) {
                    if (attrSku.isDelete()) {
                        //删除
                        appAttrSku.delete(attrSku.getMasku_id());
                    } else {
                        //编辑
                        appAttrSku.update()
                                .set("masku_name", attrSku.getMasku_name())
                                .set("masku_order", order)
                                .set("masku_sync", 0)
                                .eq("masku_id", attrSku.getMasku_id())
                                .update();
                    }
                } else {
                    //添加
                    entityAttrSku.setMasku_x_id(entityAttr.getX());
                    entityAttrSku.setMasku_spu_id(entityAttr.getMattr_spu_id());
                    entityAttrSku.setMasku_attr_id(entityAttr.getMattr_id());
                    entityAttrSku.setMasku_order(order);
                    entityAttrSku.setMasku_sync(0); //需要同步
                    entityAttrSku.setAutoID();
                    appAttrSku.save(entityAttrSku);
                }
                order++;
            }
        }

        if (spuAttrIdsDel.size() > 0) {
            deleteAttrSku(entitySpu, spuAttrIdsDel);
        }


        XLog.debug(this.getClass(), "同步SKU操作");
        syncAttrSku(entitySpu);

        return XReturn.getR(0);
    }

    @Override
    public XReturn deleteAttrSku(M2Spu entitySpu, List<String> attrIds) {
        if (attrIds.size() <= 0) {
            return EnumSys.MISS_VAL.getR("miss attr_id");
        }

        M2AttrService appAttr = M2AttrService.getBean();
        for (String attrId : attrIds) {
            M2Attr entityAttr = appAttr.getEntity(attrId);
            if (entityAttr == null || !entityAttr.getMattr_spu_id().equals(entitySpu.getKey())) {
                throw new XException(XReturn.getR(20231, "attr_id 异常," + attrId));
            }
            appAttr.delete(attrId);
        }

        return XReturn.getR(0);
    }

    @Override
    public XReturn syncAttrSku(M2Spu entitySpu) {
        XReturn r = XReturn.getR(0);
        M2AttrSkuService appAttrSku = M2AttrSkuService.getBean();
        XLog.debug(this.getClass(), "判断是否需要同步");
        if (!appAttrSku.isSync(entitySpu.getMspu_id())) {
            XLog.debug(this.getClass(), "无需同步");
            return XReturn.getR(20270, "无需同步");
        }
        //lock spu
        SvcM2Spu.getApp().getEntityLock(entitySpu.getMspu_id());
        //
        List<SpuAttrVo> listAttrSku = getListAttrSku(entitySpu);
        //
        List<SpuAttrData> list = getListAttrData(listAttrSku, false);
        //
        List<String> listSync = new LinkedList<>();
        //
        SvcM2Sku appSku = SvcM2Sku.getBean();
        SysStockService appLeft = SysStockService.getBean();
        //
        XLog.debug(this.getClass(), "收集属性规格ID，标记已同步");
        List<String> attrSkuIds = new LinkedList<>();
        for (SpuAttrData spuAttrData : list) {
            if (spuAttrData.getSync()) continue; //已同步pass

            XLog.debug(this.getClass(), "新建sku");
            M2Sku entitySku = appSku.getEntitySku(spuAttrData.getId0()
                    , spuAttrData.getId1()
                    , spuAttrData.getId2());
            if (entitySku == null) {
                entitySku = new M2Sku();
                entitySku.setMsku_x_id(entitySpu.getX());
                entitySku.setMsku_spu_id(entitySpu.getMspu_id());
                entitySku.setMsku_spu_id(entitySpu.getMspu_id());
                entitySku.setMsku_enable(1); //下架

                XLog.debug(this.getClass(), "保存属性规格ID");
                if (XStr.hasAnyText(spuAttrData.getId0())) {
                    entitySku.setMsku_attr_sku_00(spuAttrData.getId0());
                }
                if (XStr.hasAnyText(spuAttrData.getId1())) {
                    entitySku.setMsku_attr_sku_01(spuAttrData.getId1());
                }
                if (XStr.hasAnyText(spuAttrData.getId2())) {
                    entitySku.setMsku_attr_sku_02(spuAttrData.getId2());
                }
                entitySku.setMsku_name(spuAttrData.skuName());
                entitySku.setAutoID();
                SvcM2Sku.getApp().save(entitySku);

                XLog.debug(this.getClass(), "新建库存记录");
                SysStock entityLeft = new SysStock();
                entityLeft.setStock_x_id(entitySku.getX());
                entityLeft.setStock_app_id("mall2");
                entityLeft.setStock_id_src(entitySku.getMsku_id());
                entityLeft.setAutoID();
                appLeft.save(entityLeft);
            } else {
                XLog.debug(this.getClass(), "更新sku名称");
                M2Sku entityUpdate = new M2Sku();
                entityUpdate.setMsku_id(entitySku.getKey());
                entityUpdate.setMsku_name(spuAttrData.skuName());
                SvcM2Sku.getApp().saveOrUpdatePassEqualField(entitySku, entityUpdate);
            }
            listSync.add(spuAttrData.skuName());

            attrSkuIds.addAll(spuAttrData.attrSkuIds());
        }
        XLog.debug(this.getClass(), "标记已同步");
        appAttrSku.setSync(attrSkuIds, null);

        r.setData("list", listSync);

        return r;
    }

    /**
     * 属性规格变列表
     * 黄，红
     * 10，20
     * 变
     * 黄 10
     * 黄 20
     * 红 10
     * 红 20
     *
     * @param getSku true：获取sku数据，例：库存，价格
     */
    @Override
    public List<SpuAttrData> getListAttrData(List<SpuAttrVo> listAttrSku, Boolean getSku) {
        int attrLen = listAttrSku.size();
        if (attrLen <= 0) {
            return new LinkedList<>();
        }

        //1级
        List<SpuAttrSkuVo> ListAttrSku0 = listAttrSku.get(0).getAttr_skus();

        List<SpuAttrData> list = new LinkedList<>();
        for (SpuAttrSkuVo entityAttrSku0 : ListAttrSku0) {
            SpuAttrData data0 = new SpuAttrData();
            data0.setId0(entityAttrSku0.getMasku_id());
            data0.setName0(entityAttrSku0.getMasku_name());
            if (!entityAttrSku0.getDoSync()) { //false：未操作同步
                data0.setSync(false);
            }
            if (attrLen == 1) {
                list.add(data0);
                continue;
            }

            //2级
            List<SpuAttrSkuVo> ListAttrSku1 = listAttrSku.get(1).getAttr_skus();
            for (SpuAttrSkuVo entityAttrSku1 : ListAttrSku1) {
                SpuAttrData data1 = new SpuAttrData();
                XBean.copyProperties(data0, data1); //同步1级配置
                //
                data1.setId1(entityAttrSku1.getMasku_id());
                data1.setName1(entityAttrSku1.getMasku_name());
                if (!entityAttrSku1.getDoSync()) { //同步状态、false：未操作同步
                    data1.setSync(false);
                }
                if (attrLen == 2) {
                    list.add(data1);
                    continue;
                }

                //3级
                List<SpuAttrSkuVo> ListAttrSku2 = listAttrSku.get(2).getAttr_skus();
                for (SpuAttrSkuVo entityAttrSku2 : ListAttrSku2) {
                    SpuAttrData data2 = new SpuAttrData();
                    XBean.copyProperties(data1, data2); //同步2级配置

                    data2.setId2(entityAttrSku2.getMasku_id());
                    data2.setName2(entityAttrSku2.getMasku_name());
                    if (!entityAttrSku2.getDoSync()) { //同步状态
                        data2.setSync(false);
                    }
                    list.add(data2);
                }
            }
        }

        if (getSku) {
            List<SkuData> listSku = SvcM2Sku.getBean().getList(listAttrSku.get(0).getMattr_spu_id(), null);
            for (SpuAttrData item : list) {
                SkuData data = listSku.stream().filter(itemSku ->
                {
                    //找对应的sku记录及库存
                    return itemSku.getEntity().getMsku_attr_sku_00().equals(item.getId0())
                            && itemSku.getEntity().getMsku_attr_sku_01().equals(item.getId1())
                            && itemSku.getEntity().getMsku_attr_sku_02().equals(item.getId2());
                }).findFirst().get();
                M2Sku entitySku = data.getEntity();

                item.setEntity_sku(entitySku);
                //库存
                item.setCount_left(data.getStock_count_left());
                item.setCount_use(data.getStock_count_use());
            }
        }

        return list;
    }
}
